using System.Reflection;
using Lucene.Net.QueryParsers;
using Lucene.Net.Search;
using LuceneSearch.ContactApp.Indexing;

namespace LuceneSearch.ContactApp.Searching
{
    public class EntityQueryBuilder<T>
    {
        private readonly AnalyzerFactory analyzerFactory;

        public EntityQueryBuilder(AnalyzerFactory analyzerFactory)
        {
            this.analyzerFactory = analyzerFactory;
        }

        public Query BuildQuery(T entityCriteria)
        {
            var boolQuery = new BooleanQuery();

            var entityType = entityCriteria.GetType();

            var props = entityType.GetProperties();

            foreach (var prop in props)
            {
                if(prop.Name == "Id") continue;

                BuildQueryForProperty(entityCriteria, prop, boolQuery);
            }

            return boolQuery;
        }

        private void BuildQueryForProperty(T entityCriteria, PropertyInfo prop, BooleanQuery workingQuery)
        {
            var propValue = prop.GetValue(entityCriteria, null);

            if(!IsCriterionValue(propValue))
                return;

            var queryParser = new QueryParser(prop.Name, analyzerFactory.Create());
            workingQuery.Add(queryParser.Parse(propValue.ToString()), BooleanClause.Occur.MUST);
        }

        private static bool IsCriterionValue(object propValue)
        {
            return propValue != null && propValue.ToString() != "";
        }
    }
}